import re
import random

from flask import current_app, jsonify
from flask import make_response
from flask import redirect
from flask import request
from flask import session
from flask import url_for

from info.models import User
from info.modules.index import index
from info.modules.passport import passport_blu
from libs.yuntongxun.sms import CCP
from utils.captcha.captcha import captcha

from info import redis_store, db
from info.response_code import RET

"""
1、获取图像验证码
2、请求方式:GET
3、URL：/image_code
4、参数：image_code_id
"""
@passport_blu.route('/image_code')
def get_image_code():
    # 1.获取参数
    image_code_id = request.args.get('image_code_id')

    # 2.调用工具生成图像验证码内容
    name, text, value = captcha.generate_captcha()
    # print([name,text,value])

    # 3.保存到redis
    try:
        redis_store.set('imageCodeId_'+image_code_id,text,120)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno = 4001,errmsg = '保存redis出错了')

    # 4.返回图像
    response = make_response(value)
    response.headers['Content-Type'] = 'img'

    return response


"""
获取短信验证码
请求方式post
URL:/sms_code
参数:mobile、image_code、image_code_id
"""
@passport_blu.route('/sms_code',methods = (['POST']))
def get_sms_code():
    # 1、获取参数
    json_data = request.json
    mobile = json_data.get('mobile')
    image_code = json_data.get('image_code')
    image_code_id = json_data.get('image_code_id')

    # 2、检验参数
    #   2.1 参数是否齐全
    if not all([mobile,image_code,image_code_id]):
        return jsonify(errno=RET.PARAMERR, errmsg='参数不齐全')
    #   2.2 手机号码是否正确
    if not re.match(r"1[35789][0-9]{9}",mobile):
        return jsonify(errno=RET.PARAMERR, errmsg='手机号输入错误')

    # 3、逻辑处理
    #   3.1 获取redis数据
    try:
        redis_image_code=redis_store.get('imageCodeId_'+image_code_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.NODATA, errmsg='获取redis数据失败')
    if not redis_image_code:
        return jsonify(errno=RET.NODATA, errmsg='验证码过期')
    #   3.2 对比数据，错误则返回
    if image_code != redis_image_code:
        return jsonify(errno = RET.PARAMERR,errmsg = '验证码错误')
    #   3.3 对比成功，生成短信验证码
    sms_code_str = '%06d'%random.randint(0,999999)
    print(sms_code_str)
    #   3.4 保存redis
    try:
        redis_store.set('SMS_'+mobile,sms_code_str,RET.SMS_CODE_REDIS_EXPIRES)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DATAERR, errmsg='保存数据失败')
    #   3.5 调用第三方
    # ccp = CCP()
    # result=ccp.send_template_sms(mobile,[sms_code_str,5],1)
    # print(result)
    # if result != 0:
    #     return jsonify(errno = RET.THIRDERR,errmsg = '短信发送失败')

    # 4、返回数据
    return jsonify(errno = RET.OK,errmsg = '短信发送成功')


# URL:/register
# 请求方式：POST
# 参数：mobile，smscode,password
@passport_blu.route('/register',methods=(['POST']))
def register():
    """
    1、获取参数
    2、参数校验
    3、逻辑处理
    4、返回数据
    """
    # 1.获取参数
    json_data = request.json
    mobile = json_data.get('mobile')
    smscode = json_data.get('smscode')
    password = json_data.get('password')

    # 2.校验参数
    if not all([mobile,smscode,password]):
        return jsonify(errno = RET.NODATA, errmsg = "参数输入不齐全")
    if not re.match(r"1[35789][0-9]{9}",mobile):
        return jsonify(errno=RET.PARAMERR, errmsg='手机号输入错误')

    # 3.逻辑处理
    #   3.1从redis取出短信验证码
    try:
        redis_smscode = redis_store.get('SMS_' + mobile)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno = RET.NODATA,errmsg = "获取redis数据失败")
    if not redis_smscode:
        return jsonify(errno = RET.NODATA,errmsg = "验证码过期")
    #   3.2对比验证码，对比失败则返回信息
    if not smscode != redis_smscode:
        return jsonify(errno = RET.DBERR,errmsg = "验证码输入错误")
    else:
    #   3.3对比成功则删除验证码
        try:
            redis_store.delete('SMS_' + mobile)
        except Exception as e:
            current_app.logger.error(e)
    #   3.4注册用户（1手机是否注册过，2.创建User对象，3.添加到mysql数据库）
    #   3.4.1手机是否注册过
    if User.query.filter_by(mobile = mobile).first():
        return jsonify(errno = RET.DATAEXIST,errmsg = "用户以注册")
    #   3.4.2创建User对象
    user = User()
    user.nick_name = mobile
    user.mobile = mobile
    # TODO (令狐一郎): 密码加密处理
    user.password = password
    #   3.4.3添加到mysql数据库
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        current_app.logger.error()
        db.session.rollback()
        return jsonify(errno = RET.DATAERR,errmsg = "mysql添加数据失败")
    #   3.5设置用户登录session
    session['user_id']=user.id
    session['mobile']=user.mobile
    session['nick_name']=user.nick_name

    # 4返回数据
    return jsonify(errno = RET.OK,errmsg ="注册成功")


# URL:/login
# 请求方式:POST
# 参数：登录号、密码
@passport_blu.route('/login',methods=(['POST']))
def login():
    """
    1、获取参数
    2、校验参数
    3、逻辑处理
    4、返回数据
    """
    # 1、获取参数
    json_data = request.json
    mobile = json_data.get('mobile')
    password = json_data.get('password')

    # 2、校验参数(参数完整性\手机号码)
    if not all([mobile,password]):
        return jsonify(errno = RET.DBERR,errmsg = "输入不完整")
    if not re.match(r"1[35789][0-9]{9}",mobile):
        return jsonify(errno = RET.DBERR,errmsg = "手机号码输入不合规范")

    # 3、逻辑处理（与数据库中数据对比）
    #   3.1 判断是否注册过（查询数据库）
    try:
        us = User.query.filter_by(mobile = mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno = RET.DBERR,errmsg = "查询数据库失败")
    # if not us:
    #     return jsonify(errno = RET.DATAEXIST,errmsg="用户手机未注册")
    if not(us or password == us.password_hash(password)):
        return jsonify(errno = RET.DATAERR,errmsg = "用户名或密码错误")

    #   3.2 设置session
    print(us.mobile)
    print(us.nick_name)
    print(us.id)

    session['mobile']= us.mobile
    session['nick_name']= us.nick_name
    session['user_id'] = us.id

    # 4.返回数据

    return jsonify(errno = RET.OK,errmsg = "登录成功")


# 登出显示
# URL：/logout
#
@passport_blu.route('/logout',methods=(['POST']))
def logout():
    session.pop('mobile',None)
    session.pop('nick_name',None)
    session.pop('user_id',None)
    session.pop('is_admin',None)
    return jsonify(errno = RET.OK,errmsg = "成功退出")


